package service

import (
	"context"
	"errors"
	"smart-flow/server/config"
	"smart-flow/server/logger"
	"smart-flow/server/redis"
	"smart-flow/server/scheduler"
	"smart-flow/server/task"
	"time"

	redisLib "github.com/go-redis/redis/v8"
	"go.uber.org/zap"
)

var (
	ctScheduler scheduler.Scheduler
	cmScheduler scheduler.Scheduler
	cuScheduler scheduler.Scheduler
)

func InitDispatcher() {
	ctScheduler.Init()
	cmScheduler.Init()
	cuScheduler.Init()
	go func() {
		time.Sleep(5 * time.Second)
		loadTask(config.IspTelecom)
		time.Sleep(20 * time.Second)
		loadTask(config.IspMobile)
		time.Sleep(20 * time.Second)
		loadTask(config.IspUnicom)
	}()
}

func ShutdownDispatcher() {
	ctScheduler.Shutdown()
	cmScheduler.Shutdown()
	cuScheduler.Shutdown()
}

func DispatchTask(isp string, jobJson []byte) bool {
	switch isp {
	case config.IspTelecom:
		t := new(task.FlowTask)
		if !t.Init(jobJson, JobProcess, ctScheduler.Pausing) {
			return false
		}
		return ctScheduler.Build(t)
	case config.IspMobile:
		t := new(task.FlowTask)
		if !t.Init(jobJson, JobProcess, cmScheduler.Pausing) {
			return false
		}
		return cmScheduler.Build(t)
	case config.IspUnicom:
		t := new(task.FlowTask)
		if !t.Init(jobJson, JobProcess, cuScheduler.Pausing) {
			return false
		}
		return cuScheduler.Build(t)
	}
	return false
}

func StopTask(isp string) {
	switch isp {
	case config.IspTelecom:
		ctScheduler.Stop()
	case config.IspMobile:
		cmScheduler.Stop()
	case config.IspUnicom:
		cuScheduler.Stop()
	}
	logger.Logger.Info("[任务] Scheduler已停止", zap.String("isp", config.GetIspHuman(isp)))
}

func PauseTask(isp string) {
	switch isp {
	case config.IspTelecom:
		ctScheduler.Pause()
	case config.IspMobile:
		cmScheduler.Pause()
	case config.IspUnicom:
		cuScheduler.Pause()
	}
	logger.Logger.Info("[任务] Scheduler已暂停", zap.String("isp", config.GetIspHuman(isp)))
}

func ResumeTask(isp string) {
	switch isp {
	case config.IspTelecom:
		ctScheduler.Resume()
	case config.IspMobile:
		cmScheduler.Resume()
	case config.IspUnicom:
		cuScheduler.Resume()
	}
	logger.Logger.Info("[任务] Scheduler已恢复", zap.String("isp", config.GetIspHuman(isp)))
}

func loadTask(isp string) {
	taskData, err := redis.RDB.HGet(context.Background(), config.FlowTaskKey, isp).Result()
	if err != nil {
		if errors.Is(err, redisLib.Nil) {
			return
		}
		logger.Logger.Error("[任务] Scheduler操作Redis异常.", zap.Error(err))
		return
	}
	var t *task.FlowTask
	switch isp {
	case config.IspTelecom:
		t = new(task.FlowTask)
		if !t.Init([]byte(taskData), JobProcess, ctScheduler.Pausing) {
			return
		}
		ctScheduler.Build(t)
	case config.IspMobile:
		t = new(task.FlowTask)
		if !t.Init([]byte(taskData), JobProcess, cmScheduler.Pausing) {
			return
		}
		cmScheduler.Build(t)
	case config.IspUnicom:
		t = new(task.FlowTask)
		if !t.Init([]byte(taskData), JobProcess, cuScheduler.Pausing) {
			return
		}
		cuScheduler.Build(t)
	}
	logger.Logger.Info("[任务] Scheduler加载完成", zap.String("isp", config.GetIspHuman(isp)))
}
